﻿using System;


namespace DailyFx.Common
{
	public abstract class Resource : IDisposable
	{

		/// <summary>
		///		Indicates if the asset has been allocated.
		/// </summary>
		protected bool _allocated;

		/// <summary>
		///		Indicates if this asset has been disposed.
		/// </summary>
		protected bool _disposed;


		/// <summary>
        ///		d'tor .
        /// </summary>
		~Resource ()
        {
            this.Dispose2 ( false );
        }

		/// <summary>
		///		Checks if the underlying asset is currently allocated.
		/// </summary>
		public bool Allocated
		{
			get { return _allocated; }
		}

		/// <summary>
		///		Disposes of this asset, releasing the underlying unmanaged asset resource.
		/// </summary>
		public void Dispose ()
		{
			this.Dispose2 ( true );
			GC.SuppressFinalize(this);
		}


		/// <summary>
		///		Actual disposing logic for the finalizer.
		/// </summary>
		protected virtual void Dispose2 ( bool disposing )
		{
			if ( disposing )
			{
				if ( this._allocated )
				{
					this.FreeImpl () ;
					Check.MustTrue ( !this._allocated, "Asset failed to be disposed");
				}

				this._disposed = true;
			}
			else
			{
				if ( this._allocated )
				{
					// It'd never get to this point !!
					//	- the most likely problem is that assets released by finalizers, 
					//  - turns out to be end up being disposed in the wrong logic order .
					Check.MustTrue( !this._allocated, "Asset's leaked of DailyFx.");
				}
			}
		}

		/// <summary>
		///		Throws an exception if this asset has been disposed.
		/// </summary>
		protected void CheckAssetNotDisposed ()
		{
			if ( this._disposed )
			{
				throw new ObjectDisposedException ("DailyFxAsset");
			}
		}

		/// <summary>
		///		Implemented by the subclass to release asset's unmanaged resources .
		/// </summary>
		protected abstract void FreeImpl () ;
	}
}
